﻿using SQLite;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using TabbedTemplate.Models;

namespace TabbedTemplate.Services
{
    public class CityLocationsService : ICityLocationsService
    {
        /// <summary>
        /// 城市列表的缓存。
        /// </summary>
        public const string CityListCacheDbName = "CityListCacheDb.sqlite3";


        /// <summary>
        /// 城市列表缓存的路径。
        /// </summary>
        public static readonly string CityListCacheDbPath =
            Path.Combine(
                Environment.GetFolderPath(Environment.SpecialFolder
                    .LocalApplicationData), CityListCacheDbName);

        /// <summary>
        /// 数据库连接影子变量。
        /// </summary>
        private SQLiteAsyncConnection _cityListConnection;

        /// <summary>
        /// 数据库连接。
        /// </summary>
        private SQLiteAsyncConnection CityListConnection =>
            _cityListConnection ??= new SQLiteAsyncConnection(CityListCacheDbPath);

        // ******** 构造函数。
        /// <summary>
        /// 构造函数。
        /// </summary>
        /// <param name="preferenceStorage"></param>
        public CityLocationsService(IPreferenceStorage preferenceStorage)
        {
            _preferenceStorage = preferenceStorage;
        }

        private readonly IPreferenceStorage _preferenceStorage;

        /// <summary>
        /// 是否已经初始化。判断版本
        /// </summary>
        public bool CityListInitilized() =>
            _preferenceStorage.Get(CityListCacheConstants.VersionKey, -1) ==
            CityListCacheConstants.Version;


        /// <summary>
        /// 初始化，copy新版本数据库
        /// </summary>
        public async Task InitializeCityListAsync()
        {
            //打开文件流。
            using var dbFileStream =
                new FileStream(CityListCacheDbPath, FileMode.Create);
            //打开资源流。
            using var dbAssertStream = Assembly.GetExecutingAssembly()
                .GetManifestResourceStream(CityListCacheDbName);
            //将资源流中的内容拷贝到文件流中。
            if (dbAssertStream != null)
                await dbAssertStream.CopyToAsync(dbFileStream);

            _preferenceStorage.Set(CityListCacheConstants.VersionKey,
                CityListCacheConstants.Version);
        }

        /// <summary>
        /// 获取所有城市列表
        /// </summary>
        /// <returns></returns>
        public async Task<IList<City>> GetCityListAsync(int skip, int take) =>
            await CityListConnection.Table<City>().Skip(skip).Take(take)
                .ToListAsync();

        public async Task<IList<City>> SearchCityAsync(string param) =>
            await CityListConnection.Table<City>()
                .Where(p => p.CityName.Contains(param)).ToListAsync();

        public async Task CloseAsync() => await CityListConnection.CloseAsync();
    }
}
